#ifndef _ISOCKET_H_
#define _ISOCKET_H_

#define SOL_REUSEDDR	"reuseddr"
#define SOL_NODELAY		"nodelay"
#define SOL_LINGER		"linger"
#define SOL_KEEPLIVE	"keepalive"
#define SOL_CORK		"cork"
#define SOL_NOSIGPIPE	"nosigpipe"
#define SOL_SENDLEN		"sendbuflen"
#define SOL_RECVLEN		"recvbuflen"
#define SOL_SENDTM		"sendtime"
#define SOL_RECVTM		"recvtime"
#define SOL_CONTM		"contimeout"
#define SOL_SENDLOWAT	"sendlowat"
#define SOL_RECVLOWAT	"recvlowat"
#define SOL_ONLY_READ	"only_read"
#define SOL_ONLY_WRITE	"only_write"


interface ISocket : public IIoDevice
{
	std_method(CreateSock)() PURE;
	std_method(CloseSock)() PURE;
	std_method(IsOpen)() PURE;
	std_method(AttachSock)(_sock_t sock) PURE;
	std_method_(_sock_t, DetachSock)() PURE;
	std_method(SetOption)(LPCSTR opt, int val) PURE;
	std_method(GetOption)(LPCSTR opt, int* val) PURE;
};

// {4337751F-F25B-406C-9FB9-7BA540481BB1}
_DEFINE_IID(IID_ISocket,
	0x4337751f, 0xf25b, 0x406c, 0x9f, 0xb9, 0x7b, 0xa5, 0x40, 0x48, 0x1b, 0xb1);

#define TCP_READIO	0x10
#define TCP_WRITEIO	0x20


interface ITcpSocket : public ISocket
{
	std_method_(BUFFER_SIZE, SyncSend)(BUFFER_PTR buf, BUFFER_SIZE size) PURE;
	std_method_(BUFFER_SIZE, SyncRecv)(BUFFER_PTR buf, BUFFER_SIZE size) PURE;
	std_method(SyncConnect)(NET_ADDR addr, NET_PORT port) PURE;
	std_method(ReadIo)(IBase* pBase, event_id event) PURE;
	std_method(WriteIo)(IBase* pBase, event_id event) PURE;
	std_method(ConnectIo)(NET_ADDR addr, NET_PORT port, 
		IBase* pBase, event_id event) PURE;
};

// {37ACA045-F4F5-4481-93F9-B260EA1A1305}
_DEFINE_IID(IID_ITcpSocket,
	0x37aca045, 0xf4f5, 0x4481, 0x93, 0xf9, 0xb2, 0x60, 0xea, 0x1a, 0x13, 0x5);




interface IUdpSocket : public ISocket
{
	std_method_(BUFFER_SIZE, SyncSend)(NET_ADDR addr, NET_PORT port,
		BUFFER_PTR buf, BUFFER_SIZE size) PURE;
	std_method_(BUFFER_SIZE, SyncRecv)(NET_ADDR addr, NET_PORT port,
		BUFFER_PTR buf, BUFFER_SIZE size) PURE;
	std_method(ReadIo)(NET_ADDR addr, NET_PORT port, 
		IBase* pBase, event_id event) PURE;
	std_method(WriteIo)(NET_ADDR addr, NET_PORT port,
		IBase* pBase, event_id event) PURE;
};

// {7DB4FEA2-E7E2-4C1D-A5D6-751CA0CA07EA}
_DEFINE_IID(IID_IUdpSocket,
	0x7db4fea2, 0xe7e2, 0x4c1d, 0xa5, 0xd6, 0x75, 0x1c, 0xa0, 0xca, 0x7, 0xea);

//////////////////////////////////////////////////////////////////////////
interface IListen : public ISocket
{
	std_method(Listen)(NET_ADDR addr, NET_PORT port) PURE;
	std_method(Accept)(IBase* pBase) PURE;
};

// {BB9DA617-80BE-4E04-8EB4-13CF43F1EBD1}
_DEFINE_IID(IID_IListen,
	0xbb9da617, 0x80be, 0x4e04, 0x8e, 0xb4, 0x13, 0xcf, 0x43, 0xf1, 0xeb, 0xd1);

interface IAcceptListen : public IBase
{
	std_method(Accept)(IBase* pBase, _sock_t s, event_id error_code) PURE;
};

// {8221E95A-6E9F-4ADF-8F75-811BBC6DFBD0}
_DEFINE_IID(IID_IAcceptListen,
	0x8221e95a, 0x6e9f, 0x4adf, 0x8f, 0x75, 0x81, 0x1b, 0xbc, 0x6d, 0xfb, 0xd0);


interface ITcpListen : public IListen
{
	std_method(BindAccept)(IBase* pAccept) PURE;
	std_method(UnBindAccpet)() PURE;
};

// {829C3A23-4D1C-420A-BFAD-646A1924AA15}
_DEFINE_IID(IID_ITcpListen,
	0x829c3a23, 0x4d1c, 0x420a, 0xbf, 0xad, 0x64, 0x6a, 0x19, 0x24, 0xaa, 0x15);

#endif
